package com.corpdata.system.log;

import java.lang.reflect.Method;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.corpdata.common.utils.CorpdataUtil;
import com.corpdata.system.log.entity.OptLogger;
import com.corpdata.system.log.service.OptLogService;
import com.corpdata.system.security.shiro.util.UserUtil;

/**
 * 	操作日志aop切面
 * @author 80511
 */
@Aspect
@Component
public class OptLogAspect {

	private final Logger log=LoggerFactory.getLogger(OptLogAspect.class);
	
	@Autowired
	private HttpServletRequest request;
	
	@Autowired
	private OptLogService optLogService;
	
	/**
	 *  切点 
	 */
	@Pointcut("@annotation(com.corpdata.system.log.OptLog)")
	public void optLog() {}
	
	/**
	 * 后置通知
	 */
	@After("optLog()")
	public void after(JoinPoint joinPoint) {
		log.info("对@optLog()注进行后置切入 ");
		MethodSignature ms = (MethodSignature) joinPoint.getSignature();
		try {
			Method method = joinPoint.getTarget().getClass().getDeclaredMethod(ms.getName(), ms.getParameterTypes());
			OptLog opLog = method.getAnnotation(OptLog.class);
		
			OptLogger optLogger=null;
			if(opLog.auto()) {//自动封装日志对象
				optLogger=new OptLogger();
				baseInfo(optLogger);
				optLogger.setOptModule(opLog.module());//从注解中获取模式信息
				optLogger.setOptInfo(opLog.info());//详情
				optLogger.setRemark(opLog.remark());//备注
			}else {
				optLogger=OptLogConstant.OPT_LOG.get();//获取注解变量中的对象
				OptLogConstant.OPT_LOG.set(null);
				if(optLogger!=null) {
					baseInfo(optLogger);
				}else {
					log.warn("使用了@optLog()注解atuo=false，但是并没有向注解变量OptLogConstant.OPT_LOG中写入日志对象a");
				}
			}
			//插入日志对象
			if(optLogger!=null)optLogService.addOptLogger(optLogger);
			
		} catch (NoSuchMethodException | SecurityException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 	封装基础信息
	 * @param optLogger
	 */
	private void baseInfo(OptLogger optLogger) {
		optLogger.setId(CorpdataUtil.getUUID());//设置id
		optLogger.setOptUser(UserUtil.getCurrentUserid());//当前用户id
		optLogger.setIpAddress(CorpdataUtil.getIpAddress(request));//当前ip
		optLogger.setCreated(new Date());//创建时间
		optLogger.setReferer(request.getHeader("Referer").replaceAll("(http|https)://[\\w\\.:]++", ""));//请求url
		optLogger.setRequestUrl(request.getRequestURI());//当前controller对应url 
	}
}
